package com.think.cloud.thinkshop.mall.service.statistics.impl;

import cn.hutool.core.util.NumberUtil;
import com.think.cloud.thinkshop.mall.controller.admin.index.dto.StatisticalTrendViewDTO;
import com.think.cloud.thinkshop.mall.controller.admin.index.vo.IndexStatisticsReqVO;
import com.think.cloud.thinkshop.mall.controller.admin.index.vo.IndexStatisticsRespVO;
import com.think.cloud.thinkshop.mall.service.aftersales.IAfterSalesService;
import com.think.cloud.thinkshop.mall.service.memberuser.IMemberUserService;
import com.think.cloud.thinkshop.mall.service.order.IOrderDetailService;
import com.think.cloud.thinkshop.mall.service.order.IOrderService;
import com.think.cloud.thinkshop.mall.service.statistics.IStatisticsService;
import com.think.cloud.thinkshop.mall.service.uv.AppUVService;
import com.think.cloud.thinkshop.mall.service.websitesetting.IWebsiteSettingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class StatisticsServiceImpl implements IStatisticsService {
    DateTimeFormatter YYYY_MM_DD_HH_MM_SS = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    DateTimeFormatter YYYY_MM_DD = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    @Autowired
    private IOrderService orderService;
    @Autowired
    private IMemberUserService memberUserService;
    @Autowired
    private IOrderDetailService orderDetailService;
    @Autowired
    private IWebsiteSettingService websiteSettingService;
    @Autowired
    private AppUVService appUVService;
    @Autowired
    private IAfterSalesService afterSalesService;

    @Override
    public IndexStatisticsRespVO indexStatistics(IndexStatisticsReqVO vo) {
        //获取配置时区和系统时区的差值
//        int zoneTimeDiff = getZoneTimeDiff(websiteSettingService.getCache().getTimeZone());
//
//        String startTime = buildSearchTime(vo.getStartTime(), zoneTimeDiff);
//        String endTime = buildSearchTime(vo.getEndTime(), zoneTimeDiff);
        String startTime = vo.getStartTime();
        String endTime = vo.getEndTime().split(" ")[0]+" 23:59:59";

        //范围内的日期
        List<String> dateRange = generateDateRange(startTime, endTime);

        //订单笔数
        List<StatisticalTrendViewDTO> ordersCountView = orderService.orderCountTrend(startTime, endTime);
        List<BigDecimal> ordersCountTrend = generateTrend(dateRange, ordersCountView);
        BigDecimal ordersCount = sumTrend(ordersCountTrend);
        //营收总数
        List<StatisticalTrendViewDTO> turnoverTotalView = orderService.turnoverTotalTrend(startTime, endTime);
        List<BigDecimal> turnoverTotalTrend = generateTrend(dateRange, turnoverTotalView);
        BigDecimal turnoverTotal = sumTrend(turnoverTotalTrend);
        //售后订单数
        List<StatisticalTrendViewDTO> saledOrderCountView = afterSalesService.saledOrderCountTrend(startTime, endTime);
        List<BigDecimal> saledOrderCountTrend = generateTrend(dateRange, saledOrderCountView);
        BigDecimal saledOrderCount = sumTrend(saledOrderCountTrend);
        //售后订单总额
        List<StatisticalTrendViewDTO> saledOrdersTotalView = afterSalesService.saledOrderAmountTrend(startTime, endTime);
        List<BigDecimal> saledOrdersTotalTrend = generateTrend(dateRange, saledOrdersTotalView);
        BigDecimal saledOrdersTotal = sumTrend(saledOrdersTotalTrend);
        //新增客户趋势
        List<StatisticalTrendViewDTO> newMemberCountView = memberUserService.newMemberCountTrend(startTime, endTime);
        List<BigDecimal> newMemberCountTrend = generateTrend(dateRange, newMemberCountView);
        BigDecimal newMemberCount = sumTrend(newMemberCountTrend);
        //支付人数
        double payUserCount = orderService.payUserCount(startTime, endTime);
        //uv
        double uvRecordTotal = appUVService.getRecordTotal(startTime, endTime);
        return IndexStatisticsRespVO.builder()
                //订单笔数
                .ordersCount(ordersCount)
                .ordersCountTrend(ordersCountTrend)
                //营收总额
                .turnoverTotal(turnoverTotal)
                .turnoverTotalTrend(turnoverTotalTrend)
                //售后订单数
                .saledOrdersCount(saledOrderCount)
                .saledOrdersCountTrend(saledOrderCountTrend)
                //售后订单总额
                .saledOrdersTotal(saledOrdersTotal)
                .saledOrdersTotalTrend(saledOrdersTotalTrend)
                //客户总数（所有）
                .memberCount(memberUserService.memberUserCount())
                //新增客户数
                .newMemberCount(newMemberCount)
                .newMemberCountTrend(newMemberCountTrend)
                //订单转化率=订单总数/网站访问UV*100%
                .orderConvertRate(decimalFormat(ordersCount.doubleValue(), uvRecordTotal))
                //付款转化率=支付买家数/访客数UV*100%
                .payConvertRate(decimalFormat(payUserCount, uvRecordTotal))
                .trendDateRange(dateRange)
                .build();
    }
    /**
     * 配置时区和系统时区的差值
     *
     * @param configZoneStr
     * @return
     */
    private static int getZoneTimeDiff(String configZoneStr) {
        //系统时区
        int sysZone = Integer.parseInt(getSysZoneStr());
        //配置的时区
        int configZone = Integer.parseInt(configZoneStr);
        return sysZone - configZone;
    }

    /**
     * 获取系统时区字符
     */
    private static String getSysZoneStr() {
        // 获取系统默认时区
        ZoneId sysZoneId = ZoneId.systemDefault();
        // 获取当前时间以及时区信息
        ZonedDateTime zonedDateTime = ZonedDateTime.now(sysZoneId);
        // 获取时区偏移量
        int offsetHours = zonedDateTime.getOffset().getTotalSeconds() / 3600;
        return (offsetHours >= 0 ? "+" : "-") + String.format("%02d", Math.abs(offsetHours));
    }

    // 构建实际查询时间
    public String buildSearchTime(String time, int zoneTimeDiff) {
        LocalDateTime parse = LocalDateTime.parse(time, YYYY_MM_DD_HH_MM_SS);
        return parse.minusHours(zoneTimeDiff).format(YYYY_MM_DD_HH_MM_SS);
    }

    //百分比格式化
    public static String decimalFormat(double molecule, double denominator) {
        if (denominator == 0.0) {
            return "0%";
        }
        return NumberUtil.decimalFormat("#.##%", molecule / denominator);
    }

    //总数统计
    private BigDecimal sumTrend(List<BigDecimal> trend) {
        return trend.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    //统计趋势填充空值为0
    private List<BigDecimal> generateTrend(List<String> dateRange, List<StatisticalTrendViewDTO> statisticalView) {
        List<BigDecimal> result = new ArrayList<>();
        Map<String, BigDecimal> memberRegisterTrendMap = statisticalView
                .stream()
                .collect(Collectors.toMap(StatisticalTrendViewDTO::getDateStr, StatisticalTrendViewDTO::getValue));
        for (String dateStr : dateRange) {
            BigDecimal value = memberRegisterTrendMap.get(dateStr);
            result.add(value == null ? BigDecimal.ZERO : value);
        }
        return result;
    }

    /**
     * 构建查询的日期范围
     *
     * @param startDateStr
     * @param endDateStr
     * @return
     */
    public List<String> generateDateRange(String startDateStr, String endDateStr) {
        LocalDateTime startDate = LocalDateTime.parse(startDateStr, YYYY_MM_DD_HH_MM_SS);
        LocalDateTime endDate = LocalDateTime.parse(endDateStr, YYYY_MM_DD_HH_MM_SS);

        List<String> dates = new ArrayList<>();
        LocalDateTime currentDate = startDate;

        while (!currentDate.isAfter(endDate)) {
            dates.add(currentDate.format(YYYY_MM_DD));
            currentDate = currentDate.plusDays(1);
        }
        return dates;
    }

}
